#pragma once

#include "NodeTable.h"
#include "Utilities.h"

NodeTable::NodeTable(void){
	lineTable = LineTableType();
	nodeTable = NodeTableType();
}

NodeTable::~NodeTable(void){
	clear();
}

void NodeTable::clear(){
	lineTable.clear();
	nodeTable.clear();
}

// insert reference of node with the given line, returns status of operation
bool NodeTable::insertNode(Type::Index::Line line, TreeNode* node){

	// invalid line index or node pointer or line/node pointer already exist in the table
	if(!Utilities::isValidLineIndex(line) || !Utilities::isValidNode(node) 
		|| isLineExistInNode(line) || isNodeExistInLine(node)){
			return false;
	}

	/*********************lineTable***************************/	
	lineTable.insert(std::make_pair<TreeNode*, Type::Index::Line>(node, line));

	/*********************nodeTable***************************/
	nodeTable.insert(std::make_pair<Type::Index::Line, TreeNode*>(line, node));

	return true;
}

// get node with the given line
TreeNode* NodeTable::getNodeByLine(Type::Index::Line line){

	TreeNode* node = NULL;
	if(Utilities::isValidLineIndex(line) && nodeTable.size() > 0  && isLineExistInNode(line)){
		node = nodeTable.at(line);
	}

	return node;
}

// get the list of lines associated with the given reference of node
Type::Index::Line NodeTable::getLineByNode(TreeNode* node){

	if(Utilities::isValidNode(node) && !lineTable.empty()  && isNodeExistInLine(node)){
		return lineTable.at(node);
	}else{
		return -1;
	}
}

// check for exsistence of the given node
bool NodeTable::isNodeExistInLine(TreeNode* node){
	return lineTable.find(node) != lineTable.end();
}

// check for exsistence of the given line
bool NodeTable::isLineExistInNode(Type::Index::Line line){
	return nodeTable.find(line) != nodeTable.end();
}